﻿/***************************************************************************/
/// <summary>
///  <title>SLIC JobController</title>
///  <description>JobController for Add, View of Jobs</description>
///  <copyRight>Copyright (c) 2011</copyRight>
///  <company>IronOne Technologies (Pvt)Ltd</company>
///  <createdOn>2011-09-12</createdOn>
///  <author>Lushanthan Sivaneasharajah</author>
///  <modification>
///     <modifiedBy></modifiedBy>
///      <modifiedDate></modifiedDate>
///     <description></description>
///  </modification>
/// </summary>
/// 
/***************************************************************************/

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Data.SqlClient;
using System.Xml;
using System.IO;
using System.Data;
using System.Collections;
using System.Web.UI.WebControls;
using System.Configuration;
using System.Globalization;
using System.Net.Mail;
using System.Collections.Specialized;
using System.Threading;

#region SLICReferences

using SLIC.Models.Job;
using SLIC.Models.EntityModel;
using SLIC.Models.Mapper;
using SLIC.Models.Enums;
using SLIC.Models.VehicleArrays;

#endregion SLICReferences

#region ThirdPartyReferences
using log4net;
using MvcContrib.Pagination;
#endregion ThirdPartyReferences

namespace SLIC.Controllers
{
    public class JobController : BaseController
    {
        protected static readonly ILog log = LogManager.GetLogger("root");
        //
        // GET: /Job/
        public ActionResult Index()
        {
            // return View();
            //Goes to GetAllJobs action on index
            return RedirectToAction("GetAllJobs");
        }

        /// <summary>Gets the job number list related to a vehicle number.</summary>
        /// <param name="VehNo">Vehicle Number string</param>
        ///<returns>
        ///List of Job Numbers
        ///</returns>
        ///<exception cref="">
        ///Vehicle number cannot be null or empty
        ///no jobs found
        ///database errors
        /// </exception>        
        /// <remarks></remarks> 
        /// 
        public ActionResult SearchByVehicleNo(string RefNo)
        {
            //logged on entry
            log.Info(LogPoint.Entry.ToString() + "," + this.ControllerContext.Controller.ToString() + ",Search By Vehicle No," + User.Identity.Name + ",[Params=(Search String:" + RefNo + ")]");
            List<string> jobNumbers = new List<string>();//returns the job numbers list to the view.

            try
            {
                //check if parameter is valid
                if (String.IsNullOrEmpty(RefNo))
                {
                    throw new GenException(660, "Vehicle number cannot be null or empty");
                }

                using (SLICEntities context = DataObjectFactory.CreateContext())
                {
                    RefNo = RefNo.ToUpper(); //vehicle numbers are saved to uppercase in database
                    //Search by Vehicle No
                    jobNumbers = (from j in context.Jobs
                                  where j.VehicleNo == RefNo
                                  select j).OrderByDescending(m => m.Id).Select(j => j.JobNo).ToList();

                    if (jobNumbers.Count == 0)
                    {
                        //Search by Job No
                        jobNumbers = (from j in context.Jobs
                                      where j.JobNo == RefNo
                                      select j.JobNo).ToList();
                    }

                    if (jobNumbers.Count == 0)
                    {
                        throw new GenException(661, "No jobs found.");
                    }

                    //logged on success
                    log.Info(LogPoint.Success.ToString() + "," + this.ControllerContext.Controller.ToString() + ",Search By Vehicle No," + User.Identity.Name + ",[Params=(Search String:" + RefNo + ")]");
                }
            }
            catch (GenException ex)
            {
                //logged on exception
                log.Error(LogPoint.Failure.ToString() + "," + this.ControllerContext.Controller.ToString() + ",Search By Vehicle No," + User.Identity.Name + "," + ex.Message + ",[Params=(Search String:" + RefNo + ")]");
                ModelState.AddModelError("err", ex);
            }
            catch (EntityException ex)
            {
                //logged on exception
                log.Error(LogPoint.Failure.ToString() + "," + this.ControllerContext.Controller.ToString() + ",Search By Vehicle No," + User.Identity.Name + "," + ex.Message + ",[Params=(Search String:" + RefNo + ")]");
                ModelState.AddModelError("err", new GenException(801, "Error occurred while connecting to the entity database. Please try again later"));
            }
            catch (SqlException ex)
            {
                //logged on exception
                log.Error(LogPoint.Failure.ToString() + "," + this.ControllerContext.Controller.ToString() + ",Search By Vehicle No," + User.Identity.Name + "," + ex.Message + ",[Params=(Search String:" + RefNo + ")]");
                ModelState.AddModelError("err", new GenException(802, "Error occurred while connecting to the SQL database. Please try again later"));
            }
            catch (Exception ex)
            {
                //logged on exception
                log.Error(LogPoint.Failure.ToString() + "," + this.ControllerContext.Controller.ToString() + ",Search By Vehicle No," + User.Identity.Name + "," + ex.Message + ",[Params=(Search String:" + RefNo + ")]");
                ModelState.AddModelError("err", new GenException(400, ex.Message));
            }

            return GetFormatView("Jobs/SearchJobs.aspx", jobNumbers);
        }

        /// <summary>Gets the job details by Job number.</summary>
        /// <param name="JobNumber">Job Number</param>
        ///<returns>
        ///Job Entity
        ///</returns>
        ///<exception cref="">
        ///Job number cannot be null or empty
        ///job not found
        ///database errors
        /// </exception>        
        /// <remarks></remarks> 
        public ActionResult GetJobByJobNo(string JobNumber)
        {
            //logged on entry
            log.Info(LogPoint.Entry.ToString() + "," + this.ControllerContext.Controller.ToString() + ",Get Job By Job No," + User.Identity.Name + ",[Params=(Job number:" + JobNumber + ")]");

            try
            {
                //check if parameter is valid
                if (String.IsNullOrEmpty(JobNumber))
                {
                    throw new GenException(621, "Job number cannot be null or empty");
                }

                using (SLICEntities context = DataObjectFactory.CreateContext())
                {
                    JobNumber = JobNumber.ToUpper();//job numbers are saved as uppercase on database
                    Job job = (from j in context.Jobs.Include("Job_ReSubmissions")
                               where j.JobNo == JobNumber
                               select j).FirstOrDefault();

                    //this.SendEmail(job);// for testing

                    //if a job with the jobnumber not found
                    //Get Image Ids
                    if (job == null)
                    {
                        throw new GenException(622, "Job " + JobNumber + " not found.");
                    }

                    /*** Processing resubmissions and images***/
                    List<ImageGallery> images = job.ImageGalleries.Where(x => x.IsReSubmission == null || x.IsReSubmission == false).OrderBy(x => x.FieldId).ToList();
                    job.TotalImageCount = job.ImageGalleries.Count;
                    job.ImagesString = Settings.ProcessImageGalleryForTab(images);

                    if (job.Job_ReSubmissions!=null && job.Job_ReSubmissions.Count > 0)
                    {
                          this.SetReSubmissionsData(job.Job_ReSubmissions.ToList());
                    }
                    /***END Processing resubmissions and images***/

                    job.CSR_UserName = job.User.aspnet_Users.UserName;

                    /*
                    if (job.PoliceStation != null)
                    {
                        job.Nearest_PoliceStation = job.PoliceStation.StationName;
                    }
                    */

                    //get claim processing branch name
                    if (job.ClaimProcessingBranch != null)
                    {
                        job.ProcessingBranch = CultureInfo.CurrentCulture.TextInfo.ToTitleCase(job.ClaimProcessingBranch.BranchName.ToLower());
                    }

                    job.VehicleClassIds = job.Job_VehicleClasses.Select(x => x.VehicleClassId).ToList();

                    if (GetFormat().Equals("XML"))
                    {
                        goto Finish;
                    }

                    //beyond this line executes only for the html view (web only)
                    if (job.License_IsNew == null)
                    {
                        goto DamagedItems;
                    }
                    //if only License_IsNew has a value(true/false) vehicle classes can can be selected from there respective lists(enums)

                    Array arr = null;
                    List<SelectListItem> enums = new List<SelectListItem>();

                    if ((bool)job.License_IsNew)
                    {
                        arr = Enum.GetValues(typeof(NewLicenseVehClasses));
                        int i = 0;
                        foreach (NewLicenseVehClasses value in arr)
                        {
                            var item = new SelectListItem();
                            item.Value = ((short)value).ToString();
                            item.Text = arr.GetValue(i).ToString();
                            item.Selected = job.VehicleClassIds.Contains((short)value);
                            enums.Add(item);
                            i++;
                        }
                    }
                    else
                    {
                        arr = Enum.GetValues(typeof(OldLicenseVehClasses));
                        int i = 0;
                        foreach (OldLicenseVehClasses value in arr)
                        {

                            var item = new SelectListItem();
                            item.Value = ((short)value).ToString();
                            item.Text = arr.GetValue(i).ToString();
                            item.Selected = job.VehicleClassIds.Contains((short)value);
                            enums.Add(item);
                            i++;
                        }
                    }

                    // int i = 0;
                    //foreach (var value in arr)
                    //{

                    //    var item = new SelectListItem();
                    //    item.Value = ((short)value).ToString();
                    //    item.Text = arr.GetValue(i).ToString();// Enum.GetName(typeof(VehicleClass), value);
                    //    item.Selected = job.VehicleClassIds.Contains((short)value);
                    //    enums.Add(item);
                    //    i++;
                    //}

                    //used in views as vehicle class checkbox list source
                    ViewData["SelectedClasses"] = enums;

                DamagedItems:
                    String damagedItemString = HttpUtility.HtmlDecode(job.DamagedItems);
                    String possibleDRString = HttpUtility.HtmlDecode(job.PossibleDR);
                    String preAccDamString = HttpUtility.HtmlDecode(job.PreAccidentDamages);

                    if (String.IsNullOrEmpty(damagedItemString))
                    {
                        goto PreAccItems;
                    }

                    //damagedItemString do not have a "root" element to convert it to an xml document.
                    //So we append the root element("<DamagedItems>") to the front and behind.
                    damagedItemString = "<DamagedItems>" + damagedItemString + "</DamagedItems>";
                    XmlDocument damagedItemsDoc = new XmlDocument();

                    try
                    {
                        damagedItemsDoc.LoadXml(damagedItemString);
                    }
                    catch (Exception)
                    {
                        throw new GenException(623, "Damaged items XML is not in the correct format");
                    }

                    //returns an ArrayList of DamagedItems
                    job.DamagedItemsList = this.ProcessDamagedItemsXML(damagedItemsDoc);

                PreAccItems:
                    if (String.IsNullOrEmpty(preAccDamString))
                    {
                        goto DR;
                    }

                    //preAccDamString do not have a "root" element to convert it to an xml document.
                    //So we append the root element("<PreAccidentDamages>") to the front and behind.
                    preAccDamString = "<PreAccidentDamages>" + preAccDamString + "</PreAccidentDamages>";
                    XmlDocument preDamagedItemsDoc = new XmlDocument();

                    try
                    {
                        preDamagedItemsDoc.LoadXml(preAccDamString);
                    }
                    catch (Exception)
                    {
                        throw new GenException(623, "Pre Accident Damage items XML is not in the correct format");
                    }

                    //returns an ArrayList of  Pre- Accident Damaged Items
                    job.PreAccDamagesItemsList = this.ProcessPreDamagedItemsXML(preDamagedItemsDoc);

                DR:
                    if (String.IsNullOrEmpty(possibleDRString))
                    {
                        goto Finish;
                    }

                    //possibleDRString do not have a "root" element to convert it to an xml document.
                    //So we append the root element("<PossibleDR>") to the front and behind.
                    possibleDRString = "<PossibleDR>" + possibleDRString + "</PossibleDR>";
                    XmlDocument possibleDRDoc = new XmlDocument();

                    try
                    {
                        possibleDRDoc.LoadXml(possibleDRString);
                    }
                    catch (Exception)
                    {
                        throw new GenException(624, "PossibleDR XML is not in the correct format.");
                    }

                    //Returns a string array of Possible DR
                    job.PossibleDRList = this.ProcessPossibleDRXML(possibleDRDoc);

                Finish:
                    //logged on success
                    log.Info(LogPoint.Success.ToString() + "," + this.ControllerContext.Controller.ToString() + ",Get Job By Job No," + User.Identity.Name + ",[Params=(Job number:" + JobNumber + ")]");
                    return GetFormatView("Jobs/ViewJob.aspx", job);
                }
            }
            catch (GenException ex)
            {
                //logged on exception
                log.Error(LogPoint.Failure.ToString() + "," + this.ControllerContext.Controller.ToString() + ",Get Job By Job No," + User.Identity.Name + "," + ex.Message + ",[Params=(Job number:" + JobNumber + ")]");
                ModelState.AddModelError("err", ex);
            }
            catch (XmlException ex)
            {
                //logged on exception
                log.Error(LogPoint.Failure.ToString() + "," + this.ControllerContext.Controller.ToString() + ",Get Job By Job No," + User.Identity.Name + "," + ex.Message + ",[Params=(Job number:" + JobNumber + ")]");
                ModelState.AddModelError("err", new GenException(900, ex.Message));
            }
            catch (EntityException ex)
            {
                //logged on exception
                log.Error(LogPoint.Failure.ToString() + "," + this.ControllerContext.Controller.ToString() + ",Get Job By Job No," + User.Identity.Name + "," + ex.Message + ",[Params=(Job number:" + JobNumber + ")]");
                ModelState.AddModelError("err", new GenException(801, "Error occurred while connecting to the entity database. Please try again later"));
            }
            catch (SqlException ex)
            {
                //logged on exception
                log.Error(LogPoint.Failure.ToString() + "," + this.ControllerContext.Controller.ToString() + ",Get Job By Job No," + User.Identity.Name + "," + ex.Message + ",[Params=(Job number:" + JobNumber + ")]");
                ModelState.AddModelError("err", new GenException(802, "Error occurred while connecting to the SQL database. Please try again later"));
            }
            catch (Exception ex)
            {
                //logged on exception
                log.Error(LogPoint.Failure.ToString() + "," + this.ControllerContext.Controller.ToString() + ",Get Job By Job No," + User.Identity.Name + "," + ex.Message + ",[Params=(Job number:" + JobNumber + ")]");
                ModelState.AddModelError("err", new GenException(400, ex.Message));
            }

            return GetFormatView("Account/Error.aspx");//return View();            
        }

        private void SetReSubmissionsData(List<Job_ReSubmissions> resubmissions)
        {
           // using (resource)
            {
                foreach (Job_ReSubmissions submission in resubmissions)
                {
                    submission.CSR_UserName = submission.User.aspnet_Users.UserName;
                    submission.ImagesString = Settings.ProcessImageGalleryForTab(submission.ImageGalleries.ToList());
                }
            }
        }

        /// <summary>Gets all jobs.</summary>
        ///<returns>
        ///Returns the status of the action
        ///</returns>
        ///<exception cref="">
        ///No job found
        ///database errors
        /// </exception>        
        /// <remarks></remarks> 
        public ActionResult GetAllJobs(int? page, string searchText = "")
        {
            //logged on entry
            log.Info(LogPoint.Entry.ToString() + "," + this.ControllerContext.Controller.ToString() + ",Get All Jobs," + User.Identity.Name);
            List<JobDataModel> jobs = null;

            try
            {
                using (SLICEntities context = DataObjectFactory.CreateContext())
                {
                    //Get jobs list
                    if (searchText != "")
                    {
                        jobs = (from j in context.Jobs
                                where j.JobNo.ToLower().Contains(searchText)
                                select new JobDataModel
                                {
                                    JobId = j.Id,
                                    JobNo = j.JobNo,
                                    TimeReported = (j.TimeReported != null) ? (DateTime)j.TimeReported : (DateTime?)null,
                                    VehicleNo = j.VehicleNo,
                                    Caller_ContactNo = j.Caller_ContactNo,
                                    Caller_Name = j.Caller_Name,
                                    VehicleDescription = j.VehicleDescription
                                }).OrderByDescending(m => m.JobId).ToList();

                        if (jobs.Count == 0)
                        {
                            jobs = (from j in context.Jobs
                                    where j.VehicleNo.ToLower().Contains(searchText)
                                    select new JobDataModel
                                    {
                                        JobId = j.Id,
                                        JobNo = j.JobNo,
                                        TimeReported = (j.TimeReported != null) ? (DateTime)j.TimeReported : (DateTime?)null,
                                        VehicleNo = j.VehicleNo,
                                        Caller_ContactNo = j.Caller_ContactNo,
                                        Caller_Name = j.Caller_Name,
                                        VehicleDescription = j.VehicleDescription
                                    }).OrderByDescending(m => m.JobId).ToList();
                        }

                    }
                    else
                    {
                        jobs = (from j in context.Jobs
                                select new JobDataModel
                                {
                                    JobId = j.Id,
                                    JobNo = j.JobNo,
                                    TimeReported = (j.TimeReported != null) ? (DateTime)j.TimeReported : (DateTime?)null,
                                    VehicleNo = j.VehicleNo,
                                    Caller_ContactNo = j.Caller_ContactNo,
                                    Caller_Name = j.Caller_Name,
                                    VehicleDescription = j.VehicleDescription
                                }).OrderByDescending(m => m.JobId).ToList();
                    }
                    

                    if (jobs == null || jobs.Count == 0)
                    {
                        throw new GenException(661, "No jobs found.");
                    }

                    //logged on success
                    log.Info(LogPoint.Success.ToString() + "," + this.ControllerContext.Controller.ToString() + ",Get All Jobs," + User.Identity.Name);
                }
            }
            catch (GenException ex)
            {
                //logged on exception
                log.Error(LogPoint.Failure.ToString() + "," + this.ControllerContext.Controller.ToString() + ",Get All Jobs," + User.Identity.Name + "," + ex.Message);
                ModelState.AddModelError("err", ex);
            }
            catch (EntityException ex)
            {
                //logged on exception
                log.Error(LogPoint.Failure.ToString() + "," + this.ControllerContext.Controller.ToString() + ",Get All Jobs," + User.Identity.Name + "," + ex.Message);
                ModelState.AddModelError("err", new GenException(801, "Error occurred while connecting to the entity database. Please try again later"));
            }
            catch (SqlException ex)
            {
                //logged on exception
                log.Error(LogPoint.Failure.ToString() + "," + this.ControllerContext.Controller.ToString() + ",Get All Jobs," + User.Identity.Name + "," + ex.Message);
                ModelState.AddModelError("err", new GenException(802, "Error occurred while connecting to the SQL database. Please try again later"));
            }
            catch (Exception ex)
            {
                //logged on exception
                log.Error(LogPoint.Failure.ToString() + "," + this.ControllerContext.Controller.ToString() + ",Get All Jobs," + User.Identity.Name + "," + ex.Message);
                ModelState.AddModelError("err", new GenException(400, ex.Message));
            }

            return GetFormatView("Jobs/ViewJobs.aspx", jobs.AsQueryable().AsPagination(page ?? 1, Convert.ToInt32(ConfigurationManager.AppSettings["pageSize"])));
            //return GetFormatView("Account/Error.aspx");
        }

        /// <summary>Gets the input stream xml and adds the job to the DB</summary>        
        ///<param name="job">JobModel</param>
        ///<param>Request Input Stream XML</param>
        ///<returns>
        ///Returns the status of the action
        ///</returns>
        ///<exception cref="">
        ///XML incorrect format
        ///job number exists
        ///database errors
        /// </exception>        
        /// <remarks></remarks>     
        public ActionResult AddJob(JobDataModel job)
        {
            //logged on entry
            log.Info(LogPoint.Entry.ToString() + "," + this.ControllerContext.Controller.ToString() + ",Add Job," + User.Identity.Name);
            Job jobEntity = null; XmlDocument xmlDoc = null;

            try
            {
                // Check from where the action is called from
                if (!GetFormat().Equals("XML"))
                {
                    //Job can only be added by Android tablets
                    throw new GenException(601, "Job cannot be added via the web");
                }

                StreamReader reader = new StreamReader(Request.InputStream);
                String xmlData = reader.ReadToEnd();

                //check for input stream to convert it to the job xml
                if (String.IsNullOrEmpty(xmlData))
                {
                    throw new GenException(602, "No request input-stream attached");
                }
                xmlDoc = new XmlDocument();

                try
                {
                    xmlDoc.LoadXml(xmlData);
                }
                catch (Exception)
                {
                   // throw new GenException(900, "Request xml is not in the correct format. Please avoid using '<','>','&' characters.");
                    //Request xml not in the correct format
                    throw new GenException(900, "Please avoid using '<' '>' '&' characters");
                }

                //Converting XML data to job entity object  
                //sample "add job xml" can be found at SampleXml\Jobs\AddJobRequest.xml
                jobEntity = Mapper.ToJobEntity(xmlDoc);

                if (jobEntity == null)
                {
                    throw new GenException(608, "Job entity cannot be null");
                }

                //check whether the job number is unique
                if (!IsJobUnique(jobEntity.JobNo))
                {
                    throw new GenException(603, "Job number already exists");
                }

                using (SLICEntities context = DataObjectFactory.CreateContext())
                {
                    //save to database.
                    context.AddToJobs(jobEntity);
                    context.SaveChanges();

                    //send email on success if no images are attached
                    //Otherwise email will be sent after all the images get received. Check "ImageController/UploadImage"
                    if (jobEntity.ImageCount == null || jobEntity.ImageCount == 0)
                    {
                        this.SendJobEmail(jobEntity, false);
                    }

                    //logged on success
                    log.Info(LogPoint.Success.ToString() + "," + this.ControllerContext.Controller.ToString() + ",Add Job," + User.Identity.Name + ",[Params=(Job number:" + jobEntity.JobNo + ")]");
                }
            }
            catch (GenException ex)
            {
                //logged on exception
                log.Error(LogPoint.Failure.ToString() + "," + this.ControllerContext.Controller.ToString() + ",Add Job," + User.Identity.Name + "," + ex.Message);
                ModelState.AddModelError("err", ex);
            }
            catch (XmlException ex)
            {
                //logged on exception
                log.Error(LogPoint.Failure.ToString() + "," + this.ControllerContext.Controller.ToString() + ",Add Job," + User.Identity.Name + "," + ex.Message);
                ModelState.AddModelError("err", new GenException(900, ex.Message));
            }
            catch (EntityException ex)
            {
                //logged on exception
                log.Error(LogPoint.Failure.ToString() + "," + this.ControllerContext.Controller.ToString() + ",Add Job," + User.Identity.Name + "," + ex.Message + ",[Params=(Job number:" + jobEntity.JobNo + ")]");
                ModelState.AddModelError("err", new GenException(801, "Error occurred while connecting to the entity database. Please try again later"));
            }
            catch (SqlException ex)
            {
                //logged on exception
                log.Error(LogPoint.Failure.ToString() + "," + this.ControllerContext.Controller.ToString() + ",Add Job," + User.Identity.Name + "," + ex.Message + ",[Params=(Job number:" + jobEntity.JobNo + ")]");
                ModelState.AddModelError("err", new GenException(802, "Error occurred while connecting to the SQl database. Please try again later"));
            }
            catch (Exception ex)
            {
                //logged on exception
                log.Error(LogPoint.Failure.ToString() + "," + this.ControllerContext.Controller.ToString() + ",Add Job," + User.Identity.Name + "," + ex.Message + ",[Params=(Job number:" + jobEntity.JobNo + ")]");
                ModelState.AddModelError("err", new GenException(400, ex.Message));
            }

            return GetFormatView("Jobs/AddJob.aspx");
        }

        /// <summary>Prints the Job </summary>        
        ///<param name="jobId">Job Id</param>
        ///<param>Request Input Stream XML</param>
        ///<returns>
        ///Returns the status of the action
        ///</returns>
        ///<exception cref="">
        ///XML incorrect format
        ///job number exists
        ///database errors
        /// </exception>        
        /// <remarks></remarks> 
        public ActionResult PrintJob(int JobId)
        {
            //logged on entry
            log.Info(LogPoint.Entry.ToString() + "," + this.ControllerContext.Controller.ToString() + ",Print Job," + User.Identity.Name + ",[Params=(Job Id:" + JobId + ",Client IP:" + Request.ServerVariables["REMOTE_ADDR"] + ")]");

            try
            {
                if (!GetFormat().Equals("HTML"))
                {
                    throw new GenException(622, "Cannot print job via XML");
                }

                using (SLICEntities context = DataObjectFactory.CreateContext())
                {
                    Job job = (from j in context.Jobs
                               where j.Id == JobId
                               select j).FirstOrDefault();

                    if (job == null)
                    {
                        throw new GenException(622, "Job Id " + JobId.ToString() + " not found.");
                    }

                    job.CurrentPrintStatus = "Copy";

                    if (job.IsPrinted == null || !(bool)job.IsPrinted)
                        job.CurrentPrintStatus = "Original";

                    job.IsPrinted = true;
                    context.SaveChanges();

                    job.CSR_UserName = job.User.aspnet_Users.UserName;

                    if (job.ClaimProcessingBranch != null)
                    {
                        //job.ProcessingBranch = job.ClaimProcessingBranch.BranchName;
                        job.ProcessingBranch = CultureInfo.CurrentCulture.TextInfo.ToTitleCase(job.ClaimProcessingBranch.BranchName.ToLower());
                    }

                    job.VehicleClassIds = job.Job_VehicleClasses.Select(x => x.VehicleClassId).ToList();

                    if (job.License_IsNew == null)
                    {
                        goto DamagedItems;
                    }

                    Array arr = null;
                    List<SelectListItem> enums = new List<SelectListItem>();

                    if ((bool)job.License_IsNew)
                    {
                        arr = Enum.GetValues(typeof(NewLicenseVehClasses));
                        int i = 0;
                        foreach (NewLicenseVehClasses value in arr)
                        {
                            var item = new SelectListItem();
                            item.Value = ((short)value).ToString();
                            item.Text = arr.GetValue(i).ToString();
                            item.Selected = job.VehicleClassIds.Contains((short)value);
                            enums.Add(item);
                            i++;
                        }
                    }
                    else
                    {
                        arr = Enum.GetValues(typeof(OldLicenseVehClasses));
                        int i = 0;
                        foreach (OldLicenseVehClasses value in arr)
                        {

                            var item = new SelectListItem();
                            item.Value = ((short)value).ToString();
                            item.Text = arr.GetValue(i).ToString();
                            item.Selected = job.VehicleClassIds.Contains((short)value);
                            enums.Add(item);
                            i++;
                        }
                    }

                    //int k = 0;
                    //enums.Clear();
                    //foreach (var value in arr)
                    //{

                    //    var item = new SelectListItem();
                    //    item.Value = ((short)value).ToString();
                    //    item.Text = arr.GetValue(k).ToString();
                    //    item.Selected = job.VehicleClassIds.Contains((short)value);
                    //    enums.Add(item);
                    //    k++;
                    //}

                    ViewData["SelectedClasses"] = enums;

                DamagedItems:
                    String damagedItemString = HttpUtility.HtmlDecode(job.DamagedItems);
                    String possibleDRString = HttpUtility.HtmlDecode(job.PossibleDR);
                    String preAccDamString = HttpUtility.HtmlDecode(job.PreAccidentDamages);

                    if (String.IsNullOrEmpty(damagedItemString))
                    {
                        goto PreAccItems;
                    }

                    damagedItemString = "<DamagedItems>" + damagedItemString + "</DamagedItems>";
                    XmlDocument damagedItemsDoc = new XmlDocument();

                    try
                    {
                        damagedItemsDoc.LoadXml(damagedItemString);
                    }
                    catch (Exception)
                    {
                        throw new GenException(623, "Damaged items XML is not in the correct format");
                    }

                    //returns an ArrayList of DamagedItems
                    job.DamagedItemsList = this.ProcessDamagedItemsXML(damagedItemsDoc);

                PreAccItems:

                    if (String.IsNullOrEmpty(preAccDamString))
                    {
                        goto DR;
                    }

                    preAccDamString = "<PreAccidentDamages>" + preAccDamString + "</PreAccidentDamages>";
                    XmlDocument preDamagedItemsDoc = new XmlDocument();

                    try
                    {
                        preDamagedItemsDoc.LoadXml(preAccDamString);
                    }
                    catch (Exception)
                    {
                        throw new GenException(623, "Pre Accident Damage items XML is not in the correct format");
                    }

                    //returns an ArrayList of DamagedItems
                    job.PreAccDamagesItemsList = this.ProcessPreDamagedItemsXML(preDamagedItemsDoc);
                DR:
                    if (String.IsNullOrEmpty(possibleDRString))
                    {
                        goto Finish;
                    }

                    possibleDRString = "<PossibleDR>" + possibleDRString + "</PossibleDR>";
                    XmlDocument possibleDRDoc = new XmlDocument();

                    try
                    {
                        possibleDRDoc.LoadXml(possibleDRString);
                    }
                    catch (Exception)
                    {
                        throw new GenException(624, "PossibleDR XML is not in the correct format");
                    }

                    //Returns a string array of Possible DR
                    job.PossibleDRList = this.ProcessPossibleDRXML(possibleDRDoc);

                Finish:
                    //logged on success
                    log.Info(LogPoint.Success.ToString() + "," + this.ControllerContext.Controller.ToString() + ",Print Job," + User.Identity.Name + ",[Params=(Job Id:" + JobId + ",Client IP:" + Request.ServerVariables["REMOTE_ADDR"] + ")]");
                    return GetFormatView("Jobs/PrintJob.aspx", job);
                }
            }
            catch (GenException ex)
            {
                //logged on exception
                log.Error(LogPoint.Failure.ToString() + "," + this.ControllerContext.Controller.ToString() + ",Print Job," + User.Identity.Name + "," + ex.Message + ",[Params=(Job Id:" + JobId + ",Client IP:" + Request.ServerVariables["REMOTE_ADDR"] + ")]");
                ModelState.AddModelError("err", ex);
            }
            catch (XmlException ex)
            {
                //logged on exception
                log.Error(LogPoint.Failure.ToString() + "," + this.ControllerContext.Controller.ToString() + ",Print Job," + User.Identity.Name + "," + ex.Message + ",[Params=(Job Id:" + JobId + ",Client IP:" + Request.ServerVariables["REMOTE_ADDR"] + ")]");
                ModelState.AddModelError("err", new GenException(900, ex.Message));
            }
            catch (EntityException ex)
            {
                //logged on exception
                log.Error(LogPoint.Failure.ToString() + "," + this.ControllerContext.Controller.ToString() + ",Print Job," + User.Identity.Name + "," + ex.Message + ",[Params=(Job Id:" + JobId + ",Client IP:" + Request.ServerVariables["REMOTE_ADDR"] + ")]");
                ModelState.AddModelError("err", new GenException(801, "Error occurred while connecting to the entity database. Please try again later"));
            }
            catch (SqlException ex)
            {
                //logged on exception
                log.Error(LogPoint.Failure.ToString() + "," + this.ControllerContext.Controller.ToString() + ",Print Job," + User.Identity.Name + "," + ex.Message + ",[Params=(Job Id:" + JobId + ",Client IP:" + Request.ServerVariables["REMOTE_ADDR"] + ")]");
                ModelState.AddModelError("err", new GenException(802, "Error occurred while connecting to the SQL database. Please try again later"));
            }
            catch (Exception ex)
            {
                //logged on exception
                log.Error(LogPoint.Failure.ToString() + "," + this.ControllerContext.Controller.ToString() + ",Print Job," + User.Identity.Name + "," + ex.Message + ",[Params=(Job Id:" + JobId + ",Client IP:" + Request.ServerVariables["REMOTE_ADDR"] + ")]");
                ModelState.AddModelError("err", new GenException(400, ex.Message));
            }

            return GetFormatView("Jobs/PrintJob.aspx", null);
        }

        /// <summary>Prints the resubmission form</summary>        
        ///<param name="job">JobModel</param>
        ///<param>Request Input Stream XML</param>
        ///<returns>
        ///Returns the status of the action
        ///</returns>
        ///<exception cref="">
        ///XML incorrect format
        ///job number exists
        ///database errors
        /// </exception>        
        /// <remarks></remarks> 
        public ActionResult PrintReSubmission(int submissionId)
        {
            //logged on entry
            log.Info(LogPoint.Entry.ToString() + "," + this.ControllerContext.Controller.ToString() + ",Print Re-Submission," + User.Identity.Name + ",[Params=(Submission Id:" + submissionId + ",Client IP:" + Request.ServerVariables["REMOTE_ADDR"] + ")]");
            Job_ReSubmissions submission = null;

            try
            {
                if (!GetFormat().Equals("HTML"))
                {
                    throw new GenException(622, "Cannot print job via XML");
                }

                using (SLICEntities context = DataObjectFactory.CreateContext())
                {
                    submission = (from j in context.Job_ReSubmissions.Include("ImageGalleries")
                                  where j.ReSubmissionId == submissionId
                                  select j).FirstOrDefault();
                    
                    if (submission == null)
                    {
                        throw new GenException(622, "Submission Id " + submissionId.ToString() + " not found.");
                    }
                    
                    submission.JobNo = submission.Job.JobNo;
                    submission.CSR_UserName = submission.User.aspnet_Users.UserName;
                    //email test
                    //this.SendReSubmissionEmail(submission, true);

                    submission.CurrentPrintStatus = "Copy";

                    if (submission.IsPrinted == null || !(bool)submission.IsPrinted)
                        submission.CurrentPrintStatus = "Original";

                    submission.IsPrinted = true;
                    context.SaveChanges();
                    //  job.CSR_UserName = job.User.aspnet_Users.UserName;

                    //logged on success
                    log.Info(LogPoint.Success.ToString() + "," + this.ControllerContext.Controller.ToString() + ",Print Re-Submission," + User.Identity.Name + ",[Params=(Submission Id:" + submissionId + ",Client IP:" + Request.ServerVariables["REMOTE_ADDR"] + ")]");
                }
            }
            catch (GenException ex)
            {
                //logged on exception
                log.Error(LogPoint.Failure.ToString() + "," + this.ControllerContext.Controller.ToString() + ",Print Re-Submission," + User.Identity.Name + "," + ex.Message + ",[Params=(Submission Id:" + submissionId + ",Client IP:" + Request.ServerVariables["REMOTE_ADDR"] + ")]");
                ModelState.AddModelError("err", ex);
            }
            catch (XmlException ex)
            {
                //logged on exception
                log.Error(LogPoint.Failure.ToString() + "," + this.ControllerContext.Controller.ToString() + ",Print Re-Submission," + User.Identity.Name + "," + ex.Message + ",[Params=(Submission Id:" + submissionId + ",Client IP:" + Request.ServerVariables["REMOTE_ADDR"] + ")]");
                ModelState.AddModelError("err", new GenException(900, ex.Message));
            }
            catch (EntityException ex)
            {
                //logged on exception
                log.Error(LogPoint.Failure.ToString() + "," + this.ControllerContext.Controller.ToString() + ",Print Re-Submission," + User.Identity.Name + "," + ex.Message + ",[Params=(Submission Id:" + submissionId + ",Client IP:" + Request.ServerVariables["REMOTE_ADDR"] + ")]");
                ModelState.AddModelError("err", new GenException(801, "Error occurred while connecting to the entity database. Please try again later"));
            }
            catch (SqlException ex)
            {
                //logged on exception
                log.Error(LogPoint.Failure.ToString() + "," + this.ControllerContext.Controller.ToString() + ",Print Re-Submission," + User.Identity.Name + "," + ex.Message + ",[Params=(Submission Id:" + submissionId + ",Client IP:" + Request.ServerVariables["REMOTE_ADDR"] + ")]");
                ModelState.AddModelError("err", new GenException(802, "Error occurred while connecting to the SQL database. Please try again later"));
            }
            catch (Exception ex)
            {
                //logged on exception
                log.Error(LogPoint.Failure.ToString() + "," + this.ControllerContext.Controller.ToString() + ",Print Re-Submission," + User.Identity.Name + "," + ex.Message + ",[Params=(Submission Id:" + submissionId + ",Client IP:" + Request.ServerVariables["REMOTE_ADDR"] + ")]");
                ModelState.AddModelError("err", new GenException(400, ex.Message));
            }

            return GetFormatView("Jobs/PrintSubmission.aspx", submission);
        }


        /// <summary>Gets the input stream xml and resubmits the job to the DB</summary>        
        ///<param name="job">JobModel</param>
        ///<param>Request Input Stream XML</param>
        ///<returns>
        ///Returns the status of the action
        ///</returns>
        ///<exception cref="">
        ///XML incorrect format
        ///job number exists
        ///database errors
        /// </exception>        
        /// <remarks></remarks>     
        public ActionResult ReSubmitJob()
        {
            //logged on entry
            log.Info(LogPoint.Entry.ToString() + "," + this.ControllerContext.Controller.ToString() + ",Re-Submit Job," + User.Identity.Name);
            Job_ReSubmissions submissionEntity = null; //Job jobEntity = null;
            XmlDocument xmlDoc = null;

            try
            {
                // Check from where the action is called from
                if (!GetFormat().Equals("XML"))
                {
                    //Job can only be resubmitted by Android tablets
                    throw new GenException(601, "Job cannot be resubmitted via the web");
                }

                StreamReader reader = new StreamReader(Request.InputStream);
                String xmlData = reader.ReadToEnd();

                //check for input stream to convert it to the job xml
                if (String.IsNullOrEmpty(xmlData))
                {
                    throw new GenException(602, "No request input-stream attached");
                }
                xmlDoc = new XmlDocument();

                try
                {
                    xmlDoc.LoadXml(xmlData);
                }
                catch (Exception)
                {
                    //throw new GenException(900, "Request xml is not in the correct format. Please avoid using '<','>','&' characters.");
                    //Request xml not in the correct format
                    throw new GenException(900, "Please avoid using '<' '>' '&' characters");                  
                }

                //Check for resubmission tag
                try
                {
                    string action = xmlDoc.SelectSingleNode("/Request/Data/Job/@action").Value;
                    if (!String.Equals("resubmission", action, StringComparison.OrdinalIgnoreCase))
                    {
                        throw new GenException(908, "Only resubmissions can be performed with this action. Action name: Job/ResubmitJob");
                    }
                }
                catch (GenException)
                {
                    throw;
                }
                catch (Exception)
                {
                    throw new GenException(908, "Job action should be mentioned on submission");
                }

                //Converting XML data to resubmission job entity object  
                //sample "add job xml" can be found at SampleXml\Jobs\ResubmitJobRequest.xml
                submissionEntity = Mapper.ToReSubmissionEntity(xmlDoc);

                if (submissionEntity == null)
                {
                    throw new GenException(608, "Job entity cannot be null");
                }

                if (String.IsNullOrWhiteSpace(submissionEntity.Comment) && (submissionEntity.ImageCount == null || submissionEntity.ImageCount == 0))
                {
                    throw new GenException(612, "You must add images or a comment on resubmission");
                }

                using (SLICEntities context = DataObjectFactory.CreateContext())
                {
                    //save to databse.
                    context.AddToJob_ReSubmissions(submissionEntity);
                    context.SaveChanges();

                    //send email on success if no images are attached
                    //Otherwise email will be sent after all the images get received. Check "ImageController/UploadImage"

                    if (submissionEntity.ImageCount == null || submissionEntity.ImageCount == 0)
                    {
                        try
                        {
                            this.SendReSubmissionEmail(submissionEntity, false);
                            log.Info("Email send success.");
                        }
                        catch (Exception e)
                        {
                            log.Info("Email send failure.");
                        }                      
                    }

                    //logged on success
                    log.Info(LogPoint.Success.ToString() + "," + this.ControllerContext.Controller.ToString() + ",Re-Submit Job," + User.Identity.Name + ",[Params=(Submission Id:" + submissionEntity.ReSubmissionId + ")]");
                }
            }
            catch (GenException ex)
            {
                //logged on exception
                log.Error(LogPoint.Failure.ToString() + "," + this.ControllerContext.Controller.ToString() + ",Re-Submit Job," + User.Identity.Name + "," + ex.Message );
                ModelState.AddModelError("err", ex);
            }
            catch (XmlException ex)
            {
                //logged on exception
                log.Error(LogPoint.Failure.ToString() + "," + this.ControllerContext.Controller.ToString() + ",Re-Submit Job," + User.Identity.Name + "," + ex.Message );
                ModelState.AddModelError("err", new GenException(900, ex.Message));
            }
            catch (EntityException ex)
            {
                //logged on exception
                log.Error(LogPoint.Failure.ToString() + "," + this.ControllerContext.Controller.ToString() + ",Re-Submit Job," + User.Identity.Name + "," + ex.Message);
                ModelState.AddModelError("err", new GenException(801, "Error occurred while connecting to the entity database. Please try again later"));
            }
            catch (SqlException ex)
            {
                //logged on exception
                log.Error(LogPoint.Failure.ToString() + "," + this.ControllerContext.Controller.ToString() + ",Re-Submit Job," + User.Identity.Name + "," + ex.Message);
                ModelState.AddModelError("err", new GenException(802, "Error occurred while connecting to the SQL database. Please try again later"));
            }
            catch (Exception ex)
            {
                //logged on exception
                log.Error(LogPoint.Failure.ToString() + "," + this.ControllerContext.Controller.ToString() + ",Re-Submit Job," + User.Identity.Name + "," + ex.Message);
                ModelState.AddModelError("err", new GenException(400, ex.Message));
            }

            return GetFormatView("Jobs/AddJob.aspx");
        }

        /// <summary>Sends mail after job completion.</summary>
        /// <param name="JobNumber">Job Number</param>
        ///<returns>
        ///Job Entity
        ///</returns>
        ///<exception cref="">
        ///Job number cannot be null or empty
        ///job not found
        ///database errors
        /// </exception>        
        /// <remarks>This method is still not used in this project</remarks> 
        public ActionResult JobCompleted(string JobNumber)
        {
            //logged on entry
            log.Info(LogPoint.Entry.ToString() + "," + this.ControllerContext.Controller.ToString() + ",JobCompleted," + User.Identity.Name);

            try
            {
                //check parameter if valid
                if (String.IsNullOrEmpty(JobNumber))
                {
                    throw new GenException(621, "Job number cannot be null or empty");
                }

                //Check format
                if (!GetFormat().Equals("XML"))
                {
                    throw new GenException(601, "Job cannot be completed via the web");
                }

                using (SLICEntities context = DataObjectFactory.CreateContext())
                {
                    JobNumber = JobNumber.ToUpper();
                    Job job = (from j in context.Jobs
                               where j.JobNo == JobNumber
                               select j).FirstOrDefault();


                    if (job == null)
                    {
                        throw new GenException(622, "Job " + JobNumber + " not found.");
                    }
                    //send email on job completed.
                    this.SendJobEmail(job, true);

                    //logged on success
                    log.Info(LogPoint.Success.ToString() + "," + this.ControllerContext.Controller.ToString() + ",JobCompleted," + User.Identity.Name + ",Params," + JobNumber);
                    return GetFormatView("Jobs/ViewJob.aspx");
                }
            }
            catch (GenException ex)
            {
                //logged on exception
                log.Error(LogPoint.Failure.ToString() + "," + this.ControllerContext.Controller.ToString() + ",JobCompleted," + User.Identity.Name + ",Params," + JobNumber + "," + ex.Message);
                ModelState.AddModelError("err", ex);
            }
            catch (XmlException ex)
            {
                //logged on exception
                log.Error(LogPoint.Failure.ToString() + "," + this.ControllerContext.Controller.ToString() + ",JobCompleted," + User.Identity.Name + ",Params," + JobNumber + "," + ex.Message);
                ModelState.AddModelError("err", new GenException(900, ex.Message));
            }
            catch (EntityException ex)
            {
                //logged on exception
                log.Error(LogPoint.Failure.ToString() + "," + this.ControllerContext.Controller.ToString() + ",JobCompleted," + User.Identity.Name + ",Params," + JobNumber + "," + ex.Message);
                ModelState.AddModelError("err", new GenException(801, "Error occurred while connecting to the entity database. Please try again later"));
            }
            catch (SqlException ex)
            {
                //logged on exception
                log.Error(LogPoint.Failure.ToString() + "," + this.ControllerContext.Controller.ToString() + ",AddJob," + User.Identity.Name + ",Params," + JobNumber + "," + ex.Message);
                ModelState.AddModelError("err", new GenException(802, "Error occurred while connecting to the SQL database. Please try again later"));
            }
            catch (Exception ex)
            {
                //logged on exception
                log.Error(LogPoint.Failure.ToString() + "," + this.ControllerContext.Controller.ToString() + ",GetJobByJobNo," + User.Identity.Name + ",Params," + JobNumber + "," + ex.Message);
                ModelState.AddModelError("err", new GenException(400, ex.Message));
            }

            return GetFormatView("Account/Error.aspx");
            //return View();
        }

        #region NonAction

        ///<summary>A NonAction Method to check weather job number already exists.</summary>
        ///<param name="jobNo">Job Number</param>
        ///<returns>
        ///true/false 
        ///</returns>       
        /// <remarks></remarks> 
        [NonAction]
        private bool IsJobUnique(string jobNo)
        {
            try
            {
                using (SLICEntities context = DataObjectFactory.CreateContext())
                {
                    var jobs = from j in context.Jobs
                               where j.JobNo == jobNo
                               select j;
                    if (jobs.Count() == 0)
                    {
                        return true;
                    }
                }
            }
            catch (Exception)
            {
                throw;
            }
            return false;
        }

        /// <summary>Processes the Damaged Items XML and returns an arrayList</summary>
        /// <param name="damagedDoc">Damaged Items XML Document object</param>
        ///<returns>
        ///ArrayList
        ///</returns>   
        /// <remarks>
        /// Sample XML
        /// <DamagedItems>     
        ///<Type>Car</Type>
        ///<ItemColl>
        ///<CollectionName>FrontPart</CollectionName>
        ///<Items>
        ///<item>item1</item>
        ///<item>item2</item>
        ///</Items>
        ///</ItemColl>
        ///<Items>
        ///<item>item1</item>
        ///<item>item2</item>
        ///</Items>       
        ///</DamagedItems>
        /// End Sample XML
        /// </remarks>  
        /*
        [NonAction]
        private ArrayList ProcessDamagedItemsXML(XmlDocument damagedDoc)
        {
            ArrayList damagedAL = new ArrayList();
            goto ReturnArrayList;
            try
            {
                string vehName = damagedDoc.SelectSingleNode("/DamagedItems/Type").InnerText;// damagedDoc.ChildNodes[0].ChildNodes[1].InnerText;

                XmlNodeList nodeList = damagedDoc.SelectNodes("/DamagedItems/ItemColl");

                if (nodeList.Count == 0)
                {
                    goto TwoLevelItems;
                }

                foreach (XmlNode node in nodeList)
                {
                    string collectionName = node.SelectSingleNode("CollectionName").InnerText;

                    for (int i = 0; i < node.SelectNodes("Items/item").Count; i++)
                    {
                        // string itemName = node.SelectNodes("Items/item").Item(i).InnerText;
                        damagedAL.Add(new string[] { vehName, collectionName, node.SelectNodes("Items/item").Item(i).InnerText });
                    }
                }
                goto ReturnArrayList;

            TwoLevelItems:

                XmlNode ItemsNode = damagedDoc.SelectSingleNode("/DamagedItems/Items");

                for (int i = 0; i < ItemsNode.SelectNodes("item").Count; i++)
                {
                    damagedAL.Add(new string[] { vehName, ItemsNode.SelectNodes("item").Item(i).InnerText });
                }
            }
            catch (XmlException)
            {
                throw new GenException(625, "Error occured while processing damaged items xml.");
            }
            catch (Exception)
            {
                throw;
            }

        ReturnArrayList:
            return damagedAL;
        }
        */

        /// <summary>Processes the Damaged Items XML and returns an arrayList</summary>
        /// <param name="damagedDoc">Damaged Items XML Document object</param>
        ///<returns>
        ///ArrayList
        ///</returns>   
        /// <remarks>
        /// Sample XML
        /// <DamagedItems>     
        ///<Type>1</Type>
        ///<ItemColl>
        ///<DamagedItemData>
        ///<item>1,0,0,0</item>
        ///<item>1,1,1,0</item>
        ///<item>item1</item>
        /// </DamagedItemData>
        ///</ItemColl>        
        ///</DamagedItems>
        /// End Sample XML
        /// </remarks> 
        [NonAction]
        public ArrayList ProcessDamagedItemsXML(XmlDocument damagedDoc)
        {
            ArrayList damagedAL = new ArrayList();
            try
            {
                //Sample XML document of Damaged items
                /*
                 <DamagedItems>
                   <Type>1</Type> <!-- Bus = 1, Car = 2, Lorry = 3, Van = 4, ThreeWheeler = 5, Motorcycle = 6   ---> 
                   <ItemColl>
                     <DamagedItemData>
                       <!--Selected Array Positions-->
                       <item>0,0,0,0</item>
                       <item>0,0,1,0</item>
                       <item>0,0,2,0</item>
                       <item>0,1,0,0</item>                       
                     </DamagedItemData>
                   </ItemColl>        
                 </DamagedItems>
                 */

                XmlNode Vehnode = damagedDoc.SelectSingleNode("/DamagedItems/Type");

                if (Vehnode == null)
                {
                    goto ReturnArrayList;
                }

                Vehicles vehClass;
                try
                {
                    //Get vehicle type name
                    vehClass = (Vehicles)(short.Parse(Vehnode.InnerText));
                    //   string vehName = Enum.GetName(typeof(Vehicles), (short.Parse(Vehnode.InnerText)));// damagedDoc.ChildNodes[0].ChildNodes[1].InnerText;                       
                }
                catch (Exception)
                {
                    throw new GenException(760, "Error occurred while getting vehicle name from Damaged Items");
                }

                /*
                       bus-1
                       car-2
                       lorry-3
                       van-4
                       ThreeWheeler -5
                       Motorcycle -6
                */

                XmlNodeList nodeList = damagedDoc.SelectNodes("/DamagedItems/ItemColl/DamagedItemData/item");

                if (nodeList == null)
                {
                    goto ReturnArrayList;
                }

                foreach (XmlNode node in nodeList)
                {
                    string arrayPositionString = node.InnerText;
                    int[] arrayPosition = Array.ConvertAll<string, int>(arrayPositionString.Split(','), delegate(string s) { return int.Parse(s); });
                    //damagedAL.Add(new string[] { arrayPosition });

                    switch (vehClass)
                    {
                        case Vehicles.Bus:
                            Bus bus = new Bus();
                            damagedAL.Add(bus.GetDamagedItemList(arrayPosition));
                            break;
                        case Vehicles.Car:
                            Car car = new Car();
                            damagedAL.Add(car.GetDamagedItemList(arrayPosition));
                            break;
                        case Vehicles.Lorry:
                            Lorry lorry = new Lorry();
                            damagedAL.Add(lorry.GetDamagedItemList(arrayPosition));
                            break;
                        case Vehicles.Van:
                            Van van = new Van();
                            damagedAL.Add(van.GetDamagedItemList(arrayPosition));
                            break;
                        case Vehicles.ThreeWheeler:
                            ThreeWheeler threeWheeler = new ThreeWheeler();
                            damagedAL.Add(threeWheeler.GetDamagedItemList(arrayPosition));
                            break;
                        case Vehicles.Motorcycle:
                            Motorcycle motorcycle = new Motorcycle();
                            damagedAL.Add(motorcycle.GetDamagedItemList(arrayPosition));
                            break;
                        default:
                            break;
                    }
                    //  string[,,,] a = new string[10,15,5,5];

                    /* string[, , ,] a = new string[10, 15, 5, 5]
                       { 
                           { 
                               {
                                   {"ant", "aunt"},
                                   {"Sam", "Samantha"},
                                   {"clozapine", "quetiapine"},
                                   {"flomax", "volmax"},
                                   {"toradol", "tramadol"}
                               },   
                               {
                                   {"ant", "aunt"},
                                   {"Sam", "Samantha"},
                                   {"clozapine", "quetiapine"},
                                   {"flomax", "volmax"},
                                   {"toradol", "tramadol"}
                               },{
                                   {"ant", "aunt"},
                                   {"Sam", "Samantha"},
                                   {"clozapine", "quetiapine"},
                                   {"flomax", "volmax"},
                                   {"toradol", "tramadol"}
                               }
                           }, 
                           {
                               {
                                   {"ant", "aunt"},
                                   {"Sam", "Samantha"},
                                   {"clozapine", "quetiapine"},
                                   {"flomax", "volmax"},
                                   {"toradol", "tramadol"}
                               },
                               {
                                   {"ant", "aunt"},
                                   {"Sam", "Samantha"},
                                   {"clozapine", "quetiapine"},
                                   {"flomax", "volmax"},
                                   {"toradol", "tramadol"}
                               }
                           },
                           { 
                               {
                                   {"ant", "aunt"},
                                   {"Sam", "Samantha"},
                                   {"clozapine", "quetiapine"},
                                   {"flomax", "volmax"},
                                   {"toradol", "tramadol"}
                               },  
                               {
                                   {"ant", "aunt"},
                                   {"Sam", "Samantha"},
                                   {"clozapine", "quetiapine"},
                                   {"flomax", "volmax"},
                                   {"toradol", "tramadol"}
                               }
                           }
                       };
                     * */

                    //for (int i = 0; i < node.SelectNodes("Items/item").Count; i++)
                    //{
                    //    // string itemName = node.SelectNodes("Items/item").Item(i).InnerText;
                    //    damagedAL.Add(new string[] { vehName, collectionName, node.SelectNodes("Items/item").Item(i).InnerText });
                    //}
                }
                goto ReturnArrayList;
            }
            catch (XmlException)
            {
                throw new GenException(625, "Error occurred while processing damaged items XML");
            }
            catch (Exception)
            {
                throw;
            }

        ReturnArrayList:
            return damagedAL;
        }

        /// <summary>Processes the possible DR XML and returns an arrayList</summary>
        /// <param name="damagedDoc">Possible DR XML Document object</param>
        ///<returns>
        ///string array of possible DR items
        ///</returns>   
        /// <remarks>
        /// Sample XML
        /// <PossibleDR>        
        /// <item>item1</item>
        /// <item>item2</item>
        /// </PossibleDR>
        /// End Sample XML
        /// </remarks> 
        [NonAction]
        public string[] ProcessPossibleDRXML(XmlDocument possibleDRDoc)
        {
            //Sample XML document of Possible DR
            /*
            <PossibleDR>              
              <item>item1</item>
              <item>item2</item>
            </PossibleDR>
            */

            try
            {
                XmlNodeList nodeList = possibleDRDoc.SelectNodes("/PossibleDR/item");

                if (nodeList == null)
                    return null;

                string[] itemArray = new string[nodeList.Count];

                for (int i = 0; i < nodeList.Count; i++)
                {
                    itemArray[i] = CultureInfo.CurrentCulture.TextInfo.ToTitleCase(nodeList[i].InnerText.ToLower());
                }
                return itemArray;
            }
            catch (XmlException)
            {
                throw new GenException(626, "Error occurred while processing possible DR XML");
            }
            catch (Exception)
            {
                throw;
            }
        }

        /// <summary>Processes the Damaged Items XML and returns an arrayList</summary>
        /// <param name="damagedDoc">Damaged Items XML Document object</param>
        ///<returns>
        ///ArrayList
        ///</returns>   
        /// <remarks>
        /// Sample XML
        /// <DamagedItems>     
        ///<Type>1</Type>
        ///<ItemColl>
        ///<DamagedItemData>
        ///<item>1,0,0,0</item>
        ///<item>1,1,1,0</item>
        ///<item>item1</item>
        /// </DamagedItemData>
        ///</ItemColl>        
        ///</DamagedItems>
        /// End Sample XML
        /// </remarks> 
        [NonAction]
        public ArrayList ProcessPreDamagedItemsXML(XmlDocument damagedDoc)
        {
            //Sample XML document of Pre Accident damages
            /*
            <PreAccidentDamages>         
              <Type>1</Type>
              <ItemColl>
                <preDamagedItemData>
                  <!--Selected Array Positions-->
                  <item>0,0,0,0</item>
                  <item>0,0,1,0</item>
                  <item>0,0,2,0</item>                      
                </preDamagedItemData>
              </ItemColl>      
            </PreAccidentDamages>
            */

            ArrayList damagedAL = new ArrayList();
            try
            {
                XmlNode Vehnode = damagedDoc.SelectSingleNode("/PreAccidentDamages/Type");

                if (Vehnode == null)
                {
                    goto ReturnArrayList;
                }
                Vehicles vehClass;
                try
                {
                    vehClass = (Vehicles)(short.Parse(Vehnode.InnerText));
                    string vehName = Enum.GetName(typeof(Vehicles), (short.Parse(Vehnode.InnerText)));// damagedDoc.ChildNodes[0].ChildNodes[1].InnerText;                       
                }
                catch (Exception)
                {
                    throw new GenException(760, "Error occurred while getting vehicle name from Damaged Items");
                }
                /*
                       bus-1
                       car-2
                       lorry-3
                       van-4
                       ThreeWheeler-5
                       Motorcycle -6
                */

                XmlNodeList nodeList = damagedDoc.SelectNodes("/PreAccidentDamages/ItemColl/preDamagedItemData/item");

                if (nodeList == null)
                {
                    goto ReturnArrayList;
                }

                foreach (XmlNode node in nodeList)
                {
                    string arrayPositionString = node.InnerText;
                    int[] arrayPosition = Array.ConvertAll<string, int>(arrayPositionString.Split(','), delegate(string s) { return int.Parse(s); });
                    //damagedAL.Add(new string[] { arrayPosition });

                    switch (vehClass)
                    {
                        case Vehicles.Bus:
                            Bus bus = new Bus();
                            damagedAL.Add(bus.GetDamagedItemList(arrayPosition));
                            break;
                        case Vehicles.Car:
                            Car car = new Car();
                            damagedAL.Add(car.GetDamagedItemList(arrayPosition));
                            break;
                        case Vehicles.Lorry:
                            Lorry lorry = new Lorry();
                            damagedAL.Add(lorry.GetDamagedItemList(arrayPosition));
                            break;
                        case Vehicles.Van:
                            Van van = new Van();
                            damagedAL.Add(van.GetDamagedItemList(arrayPosition));
                            break;
                        case Vehicles.ThreeWheeler:
                            ThreeWheeler threeWheeler = new ThreeWheeler();
                            damagedAL.Add(threeWheeler.GetDamagedItemList(arrayPosition));
                            break;
                        case Vehicles.Motorcycle:
                            Motorcycle motorcycle = new Motorcycle();
                            damagedAL.Add(motorcycle.GetDamagedItemList(arrayPosition));
                            break;
                        default:
                            break;
                    }
                }

                goto ReturnArrayList;
            }
            catch (XmlException)
            {
                throw new GenException(625, "Error occurred while processing pre damaged items XML");
            }
            catch (Exception)
            {
                throw;
            }

        ReturnArrayList:
            return damagedAL;
        }

        //[NonAction]
        //private void SendEmail(Job jobEntity)
        //{
        //    try
        //    {
        //        SmtpClient client = new SmtpClient();
        //        client.Host = ConfigurationManager.AppSettings["SMTP_HOST"].ToString(); //Set your smtp host address
        //        client.Port = int.Parse(ConfigurationManager.AppSettings["SMTP_PORT"].ToString()); // Set your smtp port address
        //        client.DeliveryMethod = SmtpDeliveryMethod.Network;
        //        client.Credentials = new NetworkCredential(ConfigurationManager.AppSettings["MAIL_SERVER_USERNAME"].ToString(), ConfigurationManager.AppSettings["MAIL_SERVER_PASSWORD"].ToString()); //account name and password
        //        client.EnableSsl = true; // Set SSL = true
        //        MailDefinition mail = new MailDefinition();

        //        ListDictionary replacements = Mapper.ModelToDictionaryValues(jobEntity);

        //        mail.BodyFileName = "~/Content/templates/jobEmailTemplate.txt";
        //        mail.From = ConfigurationManager.AppSettings["MAIL_SERVER_USERNAME"].ToString();
        //        mail.Subject = "Job Details of " + jobEntity.JobNo;

        //        System.Net.Mail.MailMessage message = mail.CreateMailMessage(jobEntity.User.aspnet_Users.aspnet_Membership.Email, replacements, new System.Web.UI.Control());                
        //        client.Send(message);
        //    }
        //    catch (Exception ex)
        //    {
        //          throw;
        //    }
        //}

        ///<summary>Send Email</summary>
        ///<param name="jobEntity">Job Entity</param>
        ///<param name="hasImages">Whether Images have been attached</param>
        /// <remarks></remarks> 
        [NonAction]
        internal void SendJobEmail(Job jobEntity, bool hasImages)
        {
            try
            {
                System.Net.Mail.MailMessage message = this.CreateJobMessage(jobEntity);
                //if job has images attach them.
                if (hasImages)
                {
                    this.AttachJobImagesToMail(message, jobEntity);
                }

                //start sending email from a separate thread
                Email e = new Email(message);
                Thread thread = new Thread(new ThreadStart(e.StartMailThread));
                thread.Start();
            }
            catch (Exception ex)
            {
                //log on exception
                log.Error(LogPoint.Failure.ToString() + ",SendEmail," + User.Identity.Name + ",JobNo=" + jobEntity.JobNo + "," + ex.Message);
            }
        }

        ///<summary>Send Email</summary>
        ///<param name="jobEntity">Job Entity</param>
        ///<param name="hasImages">Whether Images have been attached</param>
        /// <remarks></remarks> 
        [NonAction]
        internal void SendReSubmissionEmail(Job_ReSubmissions submission, bool hasImages)
        {
           // log.Info(LogPoint.Entry.ToString() + ",SendReSubmissionEmail," + User.Identity.Name + "," + ",[Params=(Submission Id:" + submission.ReSubmissionId + ")]");
            try
            {
                submission.JobNo = submission.Job.JobNo;
                log.Info(submission.JobNo);
                submission.CSR_UserName = submission.User.aspnet_Users.UserName;
                log.Info(submission.CSR_UserName);
                System.Net.Mail.MailMessage message = this.CreateReSubmissionMessage(submission);
                //if job has images attach them.
                if (hasImages)
                {
                    this.AttachSubmissionImagesToMail(message, submission);
                }

                //start sending email from a separate thread
                Email e = new Email(message);
                Thread thread = new Thread(new ThreadStart(e.StartMailThread));
                thread.Start();
            }
            catch (Exception ex)
            {
                //log on exception
                log.Error(LogPoint.Failure.ToString() + ",SendEmail," + User.Identity.Name + ",JobNo=" + submission.JobNo + "," + ex.Message);
            }
        }

        ///<summary>Create Job message for the email body</summary>
        ///<param name="jobEntity">Job Entity</param>
        /// <remarks></remarks> 
        [NonAction]
        private MailMessage CreateJobMessage(Job jobEntity)
        {
            MailDefinition mail = new MailDefinition();
            ListDictionary replacements = Mapper.JobToDictionaryValues(jobEntity);
            mail.BodyFileName = "~/Content/templates/jobEmailTemplate.txt";
            mail.From = ConfigurationManager.AppSettings["MAIL_SERVER_USERNAME"].ToString();
            mail.Subject = "Job Details of " + jobEntity.JobNo;
            //Page page = new Page();
            //Control test = (Control)page.LoadControl("~/Views/HTML/Email/EmailHelperUC.ascx");

            System.Net.Mail.MailMessage message = mail.CreateMailMessage(jobEntity.User.aspnet_Users.aspnet_Membership.Email, replacements, new System.Web.UI.Control());
            return message;
        }

        ///<summary>Create Job message for the email body</summary>
        ///<param name="jobEntity">Job Entity</param>
        /// <remarks></remarks> 
        [NonAction]
        private MailMessage CreateReSubmissionMessage(Job_ReSubmissions resubmission)
        {
            try
            {
                MailDefinition mail = new MailDefinition();
                ListDictionary replacements = Mapper.ReSubmissionToDictionaryValues(resubmission);
                mail.BodyFileName = "~/Content/templates/resubmissionEmailTemplate.txt";
                mail.From = ConfigurationManager.AppSettings["MAIL_SERVER_USERNAME"].ToString();
                mail.Subject = "Resubmission Details of " + resubmission.JobNo;
                //Page page = new Page();
                //Control test = (Control)page.LoadControl("~/Views/HTML/Email/EmailHelperUC.ascx");

                System.Net.Mail.MailMessage message = mail.CreateMailMessage(resubmission.User.aspnet_Users.aspnet_Membership.Email, replacements, new System.Web.UI.Control());
                return message;
            }
            catch (Exception e)
            {
                log.Info(e.Message);
                return null;
            }
        }

        ///<summary>Attach images to the email as attachment</summary>
        ///<param name="jobEntity">Job Entity</param>
        ///<param name="message">MailMessage Object</param>
        /// <remarks></remarks> 
        [NonAction]
        private void AttachJobImagesToMail(System.Net.Mail.MailMessage message, Job jobEntity)
        {
            try
            {
                using (SLICEntities entities = DataObjectFactory.CreateContext())
                {
                    //get image path list
                    List<string> lstImagePaths = (from d in entities.ImageGalleries
                                                  where d.JobId == jobEntity.Id
                                                  select d.ImagePath).ToList();

                    if (lstImagePaths != null && lstImagePaths.Count > 0)
                    {
                        foreach (var path in lstImagePaths)
                        {
                            if (System.IO.File.Exists(ConfigurationManager.AppSettings["ImageSavePath"].ToString() + path))
                            {
                                Attachment attachment = new Attachment(ConfigurationManager.AppSettings["ImageSavePath"].ToString() + path);
                                message.Attachments.Add(attachment);
                            }
                        }
                    }
                   // log.Info(LogPoint.Success.ToString() + ",SendEmail-AttachImages," + User.Identity.Name + ",[Params=(Job No:" + jobEntity.JobNo + ")]");
                }
            }
            catch (Exception ex)
            {
                //log On Exception
                log.Error(LogPoint.Failure.ToString() + ",SendEmail-AttachImages," + User.Identity.Name + "," + ex.Message + ",[Params=(Job No:" + jobEntity.JobNo + ")]");
                // throw;
            }
        }

        ///<summary>Attach images to the email as attachment</summary>
        ///<param name="jobEntity">Job Entity</param>
        ///<param name="message">MailMessage Object</param>
        /// <remarks></remarks> 
        [NonAction]
        private void AttachSubmissionImagesToMail(System.Net.Mail.MailMessage message, Job_ReSubmissions submission)
        {           
            try
            {
                // log.Info(LogPoint.Entry.ToString() + ",SendEmail-AttachSubmissionImages," + User.Identity.Name + "," + ",[Params=(Submission Id:" + submission.ReSubmissionId + ")]");
                using (SLICEntities entities = DataObjectFactory.CreateContext())
                {
                    //get image path list
                    List<ImageGallery> imageGallery = (from s in entities.Job_ReSubmissions
                                                       where s.ReSubmissionId == submission.ReSubmissionId
                                                       select s.ImageGalleries).FirstOrDefault().ToList();


                    if (imageGallery != null && imageGallery.Count > 0)
                    {
                        foreach (ImageGallery gallery in imageGallery)
                        {
                            if (System.IO.File.Exists(ConfigurationManager.AppSettings["ImageSavePath"].ToString() + gallery.ImagePath))
                            {
                                Attachment attachment = new Attachment(ConfigurationManager.AppSettings["ImageSavePath"].ToString() + gallery.ImagePath);
                                message.Attachments.Add(attachment);
                            }
                        }
                    }
                 //   log.Info(LogPoint.Success.ToString() + ",SendEmail-AttachSubmissionImages," + User.Identity.Name + ",[Params=(Submission Id:" + submission.ReSubmissionId + ")]");
                }
            }
            catch (Exception ex)
            {
                //log On Exception
                log.Error(LogPoint.Failure.ToString() + ",SendEmail-AttachSubmissionImages," + User.Identity.Name + "," + ex.Message + ",[Params=(Submission Id:" + submission.ReSubmissionId + ")]");
                // throw;
            }
        }

        /// <summary>Gets all re-submissions(visits) for a specific job.</summary>
        ///<returns>
        ///List of re-submissions
        ///</returns>
        ///<param name="jobId">Job Id of the job</param>
        ///<param name="page">Page No for pagination</param>
        ///<exception cref="">
        ///No re-submissions found
        ///database errors
        /// </exception>        
        /// <remarks></remarks> 
        public ActionResult GetReSubmissions(int jobId, int? page)
        {
            //logged on entry
            log.Info(LogPoint.Entry.ToString() + "," + this.ControllerContext.Controller.ToString() + ",Get All ReSubmissions," + User.Identity.Name);
            List<Job_ReSubmissions> visits = null;

            try
            {
                using (SLICEntities context = DataObjectFactory.CreateContext())
                {
                    //get jobs list
                    visits = (from j in context.Job_ReSubmissions
                              where j.JobId == jobId
                              select j).OrderByDescending(m => m.TimeSubmited).ToList();
                    visits.ForEach(x => x.CSR_UserName = x.User.aspnet_Users.UserName);

                    if (visits == null || visits.Count == 0)
                    {
                        throw new GenException(661, "No re-submissions found.");
                    }

                    //logged on success
                    log.Info(LogPoint.Success.ToString() + "," + this.ControllerContext.Controller.ToString() + "," + User.Identity.Name + ",[Params=(Job Id:" + jobId + ")]");
                }
            }
            catch (GenException ex)
            {
                //logged on exception
                log.Error(LogPoint.Failure.ToString() + "," + this.ControllerContext.Controller.ToString() + "," + User.Identity.Name + "," + ex.Message + ",[Params=(Job Id:" + jobId + ")]");
                ModelState.AddModelError("err", ex);
            }
            catch (SqlException ex)
            {
                //logged on exception
                log.Error(LogPoint.Failure.ToString() + "," + this.ControllerContext.Controller.ToString() + "," + User.Identity.Name + "," + ex.Message + ",[Params=(Job Id:" + jobId + ")]");
                ModelState.AddModelError("err", new GenException(802, "Error occurred while connecting to the SQL database. Please try again later"));
            }
            catch (Exception ex)
            {
                //logged on exception
                log.Error(LogPoint.Failure.ToString() + "," + this.ControllerContext.Controller.ToString() + "," + User.Identity.Name + "," + ex.Message + ",[Params=(Job Id:" + jobId + ")]");
                ModelState.AddModelError("err", new GenException(400, ex.Message));
            }

            return GetFormatView("Jobs/ReSubmissions.aspx", visits.AsQueryable().AsPagination(page ?? 1, Convert.ToInt32(ConfigurationManager.AppSettings["pageSize"])));
            //return GetFormatView("Account/Error.aspx");
        }
        #endregion NonAction

    }
}
